/**
 *  一句话思路：线段树模板题
    算法描述：无
    解决所需数据结构+算法：构建线段树的结构体 + 区间处理
**/
#include<iostream>
using namespace std;

#define lc p<<1
#define rc p<<1|1
#define N 100010
typedef long long ll;

struct tnode {
    ll l, r, add, sum;
}t[4 * N];
ll a[N];

void pushup(ll p) {
    t[p].sum = t[lc].sum + t[rc].sum;
}

void pushdown(ll p) {
    ll k = t[p].add;
    t[lc].sum += k * (t[lc].r - t[lc].l + 1);
    t[rc].sum += k * (t[rc].r - t[rc].l + 1);
    t[lc].add += k;
    t[rc].add += k;
    t[p].add = 0;
}

void built(ll p, ll l, ll r) {
    t[p] = {l, r, 0, a[l]};
    if(l == r)  return ;
    ll m = (l + r) >> 1;
    built(lc, l, m);
    built(rc, m+1, r);
    pushup(p);
}

void update(ll p, ll x, ll y, ll k) {
    if(x>t[p].r || y<t[p].l)    return;
    if(x<=t[p].l && t[p].r<=y) {
        t[p].sum += (t[p].r - t[p].l + 1) * k;
        t[p].add += k;
        return ;
    }
    pushdown(p);
    update(lc, x, y, k);
    update(rc, x, y, k);
    pushup(p);
}

ll query(ll p, ll x, ll y) {
    if(x>t[p].r || y<t[p].l)    return 0;
    if(x<=t[p].l && t[p].r<=y)  return t[p].sum;
    pushdown(p);
    return query(lc, x, y) + query(rc, x, y);
}

int main() {
    int n, m, op, x, y, k;
    cin >> n >> m;
    for(int i=1; i<=n; i++) cin >> a[i];
    built(1, 1, n);
    while(m--) {
        cin >> op >> x >> y;
        if(y < x)   continue;
        if(op == 1) {
            cin >> k;
            update(1, x, y, k);
        } else  cout << query(1, x, y) << endl;
    }

    return 0;
}